import ast
from openai import OpenAI
import re


api_key = "sk-34f5c792513c423f90b404d28b070f1f"
base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1"
model="qwen-turbo"


class LargeLanguageModel:
    def __init__(self):
        api_key = "sk-34f5c792513c423f90b404d28b070f1f"
        base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1"
        model = "qwen-turbo"
        self.client = OpenAI(api_key=api_key, base_url=base_url)
        self.model = model

    def chat(self, query: str) -> str:
        """与大语言模型进行交互"""
        completion = self.client.chat.completions.create(
            model=self.model,
            messages=[{'role': 'user', 'content': query}]
        )
        return completion.choices[0].message.content

    def parse_query(self, query: str):
        """
        使用大语言模型解析查询，提取主语和关系。
        :param query: 用户的自然语言查询
        :return: (主语, 关系) 的元组，如果解析失败则返回 None
        """
        prompt = f"""请你分析以下问题："{query}"，并提取出问题中的主语和关系，以 (主语, 关系) 的元组形式返回。如果无法提取，则返回 None。"""
        response = self.chat(prompt)
        try:
            parsed_response = ast.literal_eval(response)
            if isinstance(parsed_response, tuple) and len(parsed_response) == 2:
                return parsed_response
            else:
                return None
        except (SyntaxError, ValueError):
            return None

    def similarity_score(self, query: str, sql_candidates: list):
        """
        使用 LLM 计算 query 与每个 SQL 之间的语义相似度（范围 0~1），按得分从低到高排序
        :param query: 自然语言问题
        :param sql_candidates: List[str] SQL 候选语句
        :return: List of (SQL, similarity_score) tuples，按 score 升序排列
        """
        if isinstance(sql_candidates, str):
            sql_candidates = [
                line.strip().strip(',') for line in sql_candidates.strip().splitlines()
                if line.strip().lower().startswith("select")
            ]

        if not sql_candidates or not isinstance(sql_candidates, list):
            print(" sql_candidates 不是有效列表")
            return []

        prompt = f"""你是一个SQL语义匹配评分器。请根据以下自然语言问题，对每条SQL语句的语义相关性进行评分，范围从0到1，越接近1表示越相关。

自然语言问题：
{query}

请为以下SQL语句打分：
{chr(10).join(f"{i+1}. {sql}" for i, sql in enumerate(sql_candidates))}

返回格式：
[
  ["SQL语句", 分数]
  ...
]

只返回上述JSON数组，不要有其他说明。
"""

        response = self.chat(prompt)
        response = response.strip()

        # 🧼 清洗 markdown 代码块标记
        if response.startswith("```"):
            response = re.sub(r"```[a-zA-Z]*", "", response)
            response = response.replace("```", "").strip()

        try:
            parsed = ast.literal_eval(response)
            if not isinstance(parsed, list):
                raise ValueError("非列表结构")
            ranked = sorted(parsed, key=lambda x: x[1])
            return ranked
        except Exception as e:
            print(f" 相似度解析失败：{e}，响应：{response}")
            return []
